package org.takeback.chat.service;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.takeback.chat.entity.ComputedLHH;
import org.takeback.chat.entity.LHHModel;
import org.takeback.chat.entity.LHHModelzh;
import org.takeback.chat.entity.LHHPlan;
import org.takeback.chat.store.room.Room;
import org.takeback.chat.utils.CheckIsInUtils;
import org.takeback.chat.utils.DateUtil;
import org.takeback.chat.utils.RedEnvelopesUtils;
import org.takeback.service.BaseService;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

@Service("lHHPlanService")
public class LHHPlanService extends BaseService {

	@Autowired
	private RoomService roomService;
	
	@Transactional(readOnly = true)
	public RedEnvelopesUtils getLHHPlan() {
		//获取上次开奖时间
		Map<String, Object> p = roomService.getRoomProperties("LHH0001");
		String lastOpenDateTimeStr = p.get("conf_last_time_task_time").toString();
		System.out.println(lastOpenDateTimeStr);
		Date lastTime = DateUtil.toDate(lastOpenDateTimeStr);
		List<LHHPlan> llList = this.dao.findByHql("from LHHPlan where roomId=:roomId and createTime < :lotteryCreateTime and status=1", ImmutableMap.of("roomId", "LHH0001","lotteryCreateTime", lastTime));
		RedEnvelopesUtils relu = this.diguiHb(llList, p);
		return relu;
	}
	
	public RedEnvelopesUtils diguiHb(List<LHHPlan> llList, Map<String, Object> p) {
		RedEnvelopesUtils relu = new RedEnvelopesUtils();
		//随机出红包尾数
		List<Integer> lastRedNum = relu.getListRedMoney();
		ComputedLHH computedLHH = new ComputedLHH();
		BigDecimal countZH = new BigDecimal(0);//组合要赔的金额
		for(LHHPlan lhh: llList) {
			String plan = lhh.getPlan();
			LHHModel lhhModel = JSON.parseObject(plan, new TypeReference<LHHModel>() {});
			lhhModel.setP(p);
			computedLHH.setZiro(lhhModel.getZiro());
			computedLHH.setOne(lhhModel.getOne());
			computedLHH.setTwo(lhhModel.getTwo());
			computedLHH.setThree(lhhModel.getThree());
			computedLHH.setFour(lhhModel.getFour());
			computedLHH.setFive(lhhModel.getFive());
			computedLHH.setSix(lhhModel.getSix());
			computedLHH.setSeven(lhhModel.getSeven());
			computedLHH.setEight(lhhModel.getEight());
			computedLHH.setNine(lhhModel.getNine());
			
			computedLHH.setLongMoney(lhhModel.getLongMoney());
			computedLHH.setHuMoney(lhhModel.getHuMoney());
			computedLHH.setHeMoney(lhhModel.getHeMoney());
			Map<String, BigDecimal>  tem = dealZh(lhhModel, lastRedNum, p);
			computedLHH.setZuheMoney(tem.get("countYazhu"));//组合用户一共押了多少钱
			countZH = countZH.add(tem.get("countPeiQian"));//组合要赔的钱
		}
		Map<Integer, Integer> countMap = computedLash(lastRedNum);
		//龙虎合要赔的钱
		BigDecimal  lhhMoney = this.dealLhh(computedLHH, lastRedNum, p);
		//计算单注要赔的钱
		BigDecimal  dzMoney = this.dealDZRes(computedLHH, countMap, p);
		//所有要赔的钱 
		BigDecimal countAll = new BigDecimal(0);
		countAll = countAll.add(dzMoney).add(lhhMoney).add(countZH);
		if(computedLHH.getTotalMoney().compareTo(BigDecimal.ZERO) == 0) {
			return relu;
		}
		System.out.println(computedLHH.getTotalMoney().doubleValue() +"要赔的钱 和总金额" + countAll.doubleValue());
		if(computedLHH.getTotalMoney().compareTo(countAll) < 1) { //表示要赔的钱多余收的钱  再次计算
			diguiHb(llList, p);
		}
		return relu;
	}
	
	/**
	 * 统计组合赔多少钱  计算组合  用户一共押了多少钱
	 */
	public Map<String, BigDecimal> dealZh(LHHModel lhhModel, List<Integer> lastRedNum, Map<String, Object> p) {
		BigDecimal countPeiQian = new BigDecimal(0);
		BigDecimal countYazhu = new BigDecimal(0);
		Map<String, BigDecimal> map = new HashMap<String, BigDecimal>();
		if(lhhModel.getZh() == null || lhhModel.getZh().size() == 0) {
			return map;
		}
		//计算  如果尾号是 lastRedNum   组合需要赔多少钱
		for(LHHModelzh zh : lhhModel.getZh()){
			String key = zh.getType().toString();
			BigDecimal peilv = new BigDecimal(p.get("config_Z" + key).toString());
			boolean res = false;
			if(zh.getType() == 2) {
				if(zh.getNum1() == null && zh.getNum2() == null  && zh.getMoney() == null) continue;  
				res = CheckIsInUtils.isCheckIn(lastRedNum, zh.getNum1(), zh.getNum2());
			} else if(zh.getType() == 3) {
				if(zh.getNum1() == null && zh.getNum2() == null && zh.getNum3() == null && zh.getMoney() == null) continue;  
				res = CheckIsInUtils.isCheckIn(lastRedNum, zh.getNum1(), zh.getNum2(), zh.getNum3());
			} else if(zh.getType() == 4) {
				if(zh.getNum1() == null && zh.getNum2() == null && zh.getNum3() == null && zh.getNum4() == null && zh.getMoney() == null) continue;  
				res = CheckIsInUtils.isCheckIn(lastRedNum, zh.getNum1(), zh.getNum2(), zh.getNum3(), zh.getNum4());
			} else if(zh.getType() == 5) {
				if(zh.getNum1() == null && zh.getNum2() == null && zh.getNum3() == null && zh.getNum4() == null && zh.getNum5() == null && zh.getMoney() == null) continue;  
				res = CheckIsInUtils.isCheckIn(lastRedNum, zh.getNum1(), zh.getNum2(), zh.getNum3(), zh.getNum4(), zh.getNum5());
			}
			if(res){
				System.out.println("组合赔率" + peilv);
				System.out.println("用户押的钱是" + zh.getMoney());
				countPeiQian = countPeiQian.add(zh.getMoney().multiply(peilv));
				System.out.println("需要赔付的钱" + countPeiQian.doubleValue());
			}
			countYazhu = countYazhu.add(zh.getMoney());//每一注 用户押的钱 的和
		}
		map.put("countPeiQian", countPeiQian);
		map.put("countYazhu", countYazhu);
		return map;
	}
	//获取方案2对应倍数
	public int getPaysTwo(Room room, Integer times){
		String key = "config_Z" + times.toString();
		Object pays = room.getProperties().get(key);
		if(pays == null) {
			throw new RuntimeException("缺少方案二赔率设置");
		}
		return (int) room.getProperties().get(key);
	}
	
	
	/**
	 * 统计个数
	 * @param lastRedNum
	 * @return
	 */
	public Map<Integer, Integer> computedLash(List<Integer> lastRedNum) {
		Map<Integer, Integer> respon = new HashMap<Integer, Integer>();
		Set<Integer> uniqueSet = new HashSet<Integer>(lastRedNum);
		 for (Integer temp : uniqueSet) {
	        int count = Collections.frequency(lastRedNum, temp);
	        if(count > 0){
	        	respon.put(temp, count);
	        }
	    }
	    return respon;
	}

	/**
	 * 计算龙虎合需要赔的钱
	 */
	public BigDecimal dealLhh2(LHHModel computedLHH, List<Integer> lastRedNum, Map<String, Object> p) {
		BigDecimal count = new BigDecimal(0);
		Double pelvL = Double.parseDouble(p.get("config_L").toString());
		Double pelvH = Double.parseDouble(p.get("config_H").toString());
		Double pelvHe = Double.parseDouble(p.get("config_LHH").toString());
		Integer first = lastRedNum.get(0);
		Integer last = lastRedNum.get(4);
		if(first > last) {
			if(computedLHH.getLongMoney() != null && computedLHH.getLongMoney().compareTo(BigDecimal.ZERO) != 0) {
				count =  count.add(computedLHH.getLongMoney().multiply(new BigDecimal(pelvL)));
			}
		} else if(first == last) {
			if(computedLHH.getHuMoney() != null && computedLHH.getHuMoney().compareTo(BigDecimal.ZERO) != 0){
				count =  count.add(computedLHH.getHuMoney().multiply(new BigDecimal(pelvHe)));
			}
		} else {
			if(computedLHH.getHeMoney() != null && computedLHH.getHeMoney().compareTo(BigDecimal.ZERO) != 0){
				count =  count.add(computedLHH.getHeMoney().multiply(new BigDecimal(pelvH)));
			}
		}
		return count;
	}
	/**
	 * 计算龙虎合需要赔的钱
	 */
	public BigDecimal dealLhh(ComputedLHH computedLHH, List<Integer> lastRedNum, Map<String, Object> p) {
		BigDecimal count = new BigDecimal(0);
		Double pelvL = Double.parseDouble(p.get("config_L").toString());
		Double pelvH = Double.parseDouble(p.get("config_H").toString());
		Double pelvHe = Double.parseDouble(p.get("config_LHH").toString());
		System.out.println("处理龙虎合时候红包尾数为" + lastRedNum.toString());
		Integer first = lastRedNum.get(0);
		Integer last = lastRedNum.get(4);
		if(first > last) {
			if(computedLHH.getLongMoney() != null && computedLHH.getLongMoney().compareTo(BigDecimal.ZERO) != 0) {
				count =  count.add(computedLHH.getLongMoney().multiply(new BigDecimal(pelvL)));
			}
		} else if(first == last) {
			if(computedLHH.getHuMoney() != null && computedLHH.getHuMoney().compareTo(BigDecimal.ZERO) != 0){
				count =  count.add(computedLHH.getHuMoney().multiply(new BigDecimal(pelvHe)));
			}
		} else {
			if(computedLHH.getHeMoney() != null && computedLHH.getHeMoney().compareTo(BigDecimal.ZERO) != 0){
				count =  count.add(computedLHH.getHeMoney().multiply(new BigDecimal(pelvH)));
			}
		}
		return count;
	}
	
	
	/**
	 * 计算单注需要赔的钱
	 * @param computedLHH
	 * @param countMap
	 * @param p
	 * @return
	 */
	public BigDecimal dealDZRes(ComputedLHH computedLHH, Map<Integer, Integer> countMap, Map<String, Object> p) {
		BigDecimal count = new BigDecimal(0);
		for(Integer key : countMap.keySet()) {
			Integer Times = countMap.get(key);
			//单注每个数字对应的赔率
			Integer pelv = Integer.parseInt(p.get("config_D" + Times).toString());
			switch(key) {
			case 0:
				if(computedLHH.getZiro() != null && computedLHH.getZiro().compareTo(BigDecimal.ZERO) != 0) {
					count = count.add(computedLHH.getZiro().multiply(new BigDecimal(pelv)));
				}
				break;
			case 1:
				count = count.add(computedLHH.getOne().multiply(new BigDecimal(pelv)));
				break;
			case 2:
				count = count.add(computedLHH.getTwo().multiply(new BigDecimal(pelv)));
				break;
			case 3:
				count = count.add(computedLHH.getThree().multiply(new BigDecimal(pelv)));
				break;
			case 4:
				count = count.add(computedLHH.getFour().multiply(new BigDecimal(pelv)));
				break;
			case 5:
				count = count.add(computedLHH.getFive().multiply(new BigDecimal(pelv)));
				break;
			case 6:
				count = count.add(computedLHH.getSix().multiply(new BigDecimal(pelv)));
				break;
			case 7:
				count = count.add(computedLHH.getSeven().multiply(new BigDecimal(pelv)));
				break;
			case 8:
				count = count.add(computedLHH.getEight().multiply(new BigDecimal(pelv)));
				break;
			case 9:
				count = count.add(computedLHH.getNine().multiply(new BigDecimal(pelv)));
				break;
			}
		}
		return count;
	}
	
	/**
	 * 计算单注需要赔的钱
	 * @param computedLHH
	 * @param countMap
	 * @param p
	 * @return
	 */
	public BigDecimal dealDZRes2(LHHModel computedLHH, Map<Integer, Integer> countMap, Map<String, Object> p) {
		BigDecimal count = new BigDecimal(0);
		for(Integer key : countMap.keySet()) {
			Integer Times = countMap.get(key);
			//单注每个数字对应的赔率
			Integer pelv = Integer.parseInt(p.get("config_D" + Times).toString());
			switch(key) {
			case 0:
				if(computedLHH.getZiro() != null && computedLHH.getZiro().compareTo(BigDecimal.ZERO) != 0) {
					count = count.add(computedLHH.getZiro().multiply(new BigDecimal(pelv)));
				}
				break;
			case 1:
				if(computedLHH.getOne() != null && computedLHH.getOne().compareTo(BigDecimal.ZERO) != 0) {
					count = count.add(computedLHH.getOne().multiply(new BigDecimal(pelv)));
				}
				break;
			case 2:
				if(computedLHH.getTwo() != null && computedLHH.getTwo().compareTo(BigDecimal.ZERO) != 0) {
					count = count.add(computedLHH.getTwo().multiply(new BigDecimal(pelv)));
				}
				break;
			case 3:
				if(computedLHH.getThree() != null && computedLHH.getThree().compareTo(BigDecimal.ZERO) != 0) {
					count = count.add(computedLHH.getThree().multiply(new BigDecimal(pelv)));
				}
				break;
			case 4:
				if(computedLHH.getFour() != null && computedLHH.getFour().compareTo(BigDecimal.ZERO) != 0) {
					count = count.add(computedLHH.getFour().multiply(new BigDecimal(pelv)));
				}
				break;
			case 5:
				if(computedLHH.getFive() != null && computedLHH.getFive().compareTo(BigDecimal.ZERO) != 0) {
					count = count.add(computedLHH.getFive().multiply(new BigDecimal(pelv)));
				}
				break;
			case 6:
				if(computedLHH.getSix() != null && computedLHH.getSix().compareTo(BigDecimal.ZERO) != 0) {
					count = count.add(computedLHH.getSix().multiply(new BigDecimal(pelv)));
				}
				break;
			case 7:
				if(computedLHH.getSeven() != null && computedLHH.getSeven().compareTo(BigDecimal.ZERO) != 0) {
					count = count.add(computedLHH.getSeven().multiply(new BigDecimal(pelv)));
				}
				break;
			case 8:
				if(computedLHH.getEight() != null && computedLHH.getEight().compareTo(BigDecimal.ZERO) != 0) {
					count = count.add(computedLHH.getEight().multiply(new BigDecimal(pelv)));
				}
				break;
			case 9:
				if(computedLHH.getNine() != null && computedLHH.getNine().compareTo(BigDecimal.ZERO) != 0) {
					count = count.add(computedLHH.getNine().multiply(new BigDecimal(pelv)));
				}
				break;
			}
		}
		return count;
	}
}
